#include <muduo/net/TcpClient.h>
#include <muduo/net/EventLoop.h>
#include <functional>
#include <muduo/net/TcpConnection.h>
#include <muduo/net/InetAddress.h>
#include <muduo/base/CountDownLatch.h>
#include <muduo/net/EventLoopThread.h>
#include <iostream>
#include <string>
#include<functional>

class DictClient
{
public:
   DictClient(const std::string& ip, int port) : _connect_latch(1),
       _baseloop(loopthread.startLoop()),
       _client(_baseloop, muduo::net::InetAddress(ip, port), "DictClient")
   {
       // 设置连接事件（连接建立/管理）的回调
       _client.setConnectionCallback(std::bind(&DictClient::onConnection, this, std::placeholders::_1));
       // 设置连接消息的回调
       _client.setMessageCallback(std::bind(&DictClient::onMessage, this,
           std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
       _client.connect();
       _connect_latch.wait();
   }
   void send(const std::string msg)
   {
       if (_conn->connected() == false)
       {
           std::cout << "发送失败" << std::endl;
           return;
       }
       _conn->send(msg);

   }
private:
   void onConnection(const muduo::net::TcpConnectionPtr& con)
   {
       if (con->connected())
       {
           std::cout << "连接成功" << std::endl;
           // 计数减1
           _connect_latch.countDown();
           _conn = con;
       }
       else
       {
           std::cout << "连接断开" << std::endl;
           _conn.reset();
       }
   }

   void onMessage(const muduo::net::TcpConnectionPtr& conn,
       muduo::net::Buffer* buf,
       muduo::Timestamp t)
   {
       std::string msg = buf->retrieveAllAsString();
       std::cout << msg << std::endl;
   }

private:
   muduo::net::TcpClient _client;
   muduo::net::TcpConnectionPtr _conn;
   muduo::net::EventLoop* _baseloop;
   muduo::net::EventLoopThread loopthread; // 开辟一个线程，来进行事件循环监控，IO处理.
   // 计数
   muduo::CountDownLatch _connect_latch;
};

int main()
{
   DictClient client("127.0.0.1", 8080);
   while (1) {
       std::string msg;
       std::cin >> msg;
       client.send(msg);
   }
   return 0;
}



